
<style lang="scss" scoped>
@use "sass:math"; // 导入 sass:math 模块
.app{
  padding-bottom: 50px;
}
// 目标容器的框
.target_box{
  width: 100%;
  display: flex;
  // flex: 1;
  justify-content: center;
  align-items: center;
  margin-bottom: 30px;
  position: relative;
}
.draggable-item, .dropped-item {
  width: 45px;
  height: 45px;
border-radius: 50%;
  /* background-color: #4caf50; */
  color: white;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: grab;
}

.source-container {
  display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
gap: 10px;   
  // border: 2px dashed #ccc;
  padding: 10px;
  margin-bottom: 20px;
}

.source-item-container,.dropzone {
  margin-bottom: 10px;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  border: 0.1px dashed #aaa;
  display: flex;
  justify-content: center;
  align-items: center;
}
.source-item-container{
  position: absolute;
}
.drop-container {
  // display: flex;
  // justify-content: space-between;
  width: 400px;
  height: 380px;
  position: relative;
  display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
gap: 10px;   

  // height: 300px;
}


// 定义元素数量
// $element-count: 14;

// // 计算每个元素之间的角度
// $angle-step: 360deg / $element-count;

// .parent {
//   position: relative;
//   width: 100%;
//   height: 100%;
// }

// @for $i from 0 through $element-count {
//   $angle: ($i - 1) * $angle-step;

//   .img#{$i} {
//     position: absolute;
//     top: 50%;
//     left: 50%;
//     transform: rotate($angle) translate(-50%, -100%) translateY(-50%);
//     transform-origin: 0 0;
//   }
// // }
$element-count: 17;
$radius: 140px; // 圆环的半径
$center-x: 43%; // 圆心的X坐标
$center-y: 50%; // 圆心的Y坐标
$pi: 3.14159265359;
@function calc-position-x($angle, $radius) {
  @return $radius * cos($angle);
}

@function calc-position-y($angle, $radius) {
  @return $radius * sin($angle);
}

@for $i from 0 through $element-count {
  // $angle-deg: ($i - 1) * (360deg / $element-count) - 90deg; // 将第一个元素放在顶部
  // $angle-rad: strip-unit($angle-deg) * (pi() / 180); // 使用 strip-unit() 函数
  // 计算每个元素的角度，确保第一个元素在顶部
  // $angle-deg: ($i - 1) * (360deg / $element-count) - 90deg;
  $angle-deg: ($i - 1) * math.div(360deg, $element-count) - 90deg;
  // 将角度从度数转换为弧度
  // 使用 ($angle-deg / 1deg) 使结果无单位
  // $angle-rad: ($angle-deg / 1deg) * (3.1415 / 180);
  $angle-rad: math.div($angle-deg, 1deg) * math.div($pi, 180);
  $pos-x: calc-position-x($angle-rad, $radius);
  $pos-y: calc-position-y($angle-rad, $radius);
  .img#{$i} {
    top: calc(#{$center-y} + #{$pos-y});
    left: calc(#{$center-x} + #{$pos-x});
    // transform: translate(-50%, -50%); // 使元素的中心与定位点对齐
  }
}
.text_alert{
  position: absolute; /* 子元素绝对定位 */
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%); /* 通过偏移自身宽高的50%来居中 */
  z-index: 10;
}
.text_alert_top{
  text-align: center;
  font-weight: 550;
  margin-bottom: 15px;
}
.text_alert_top2{
  text-align: center;
  font-weight: 550;
  font-size: 1.3rem;
  margin-bottom: 15px;
}
.text_alert>p{
  font-size: 0.7rem;
  text-align: center;
}
.synopsis{
  width: 100%;
  line-height: 1.3rem;
  font-size: 0.9rem;
  margin-bottom: 15px;
}
.submit_but{
width: 100%;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
// position: fixed;
bottom: 0;
}
@keyframes rotate {
  from {
    transform: rotate(0deg); /* 初始角度 */
  }
  to {
    transform: rotate(360deg); /* 最终角度 */
  }
}

.element {
  // display: inline-block; /* 使元素保持块级显示 */
  filter: grayscale(60%); /* 将颜色转换为灰色 */
  animation: rotate 5s linear infinite; /* 5秒完成一圈，匀速旋转，循环无限次 */
  opacity: 0.7;
}
.prompt{
  position: relative;
  overflow: hidden;
}
.prompt_more{
  position: absolute;
  right: 0;
  bottom: 0;
  color: blue;
  font-family: 550;
}
</style>
<template>
 
    <!-- 目标容器 -->
  <div class="target_box">
    <div class="text_alert">
        <div v-html="result_text" v-if="submit_status" class="text_alert_top2">
          </div>
        <div v-else class="text_alert_top">
          按渐变顺序排列颜色
        </div>
        <p v-if="submit_status" >{{submit_status?'此测试结果不构成医学建议仅作参考':''}}</p>
        <p v-else >{{!containers.every(item=>item)?'测试你对色彩辨别的能力':containers.every(item=>item)?'太棒了，快去看看测试结果吧！':''}}</p>
      </div>
    <div :class="['drop-container',submit_status?'element':'']">
      
     
        <container
        :group-name="index>0?'shared':'shared1'"
        behaviour="move"
        v-for="(containerItem, index) in containers"
         @dragEnter="onDragEnter2($event,index)"
        @dragLeave="onDragLeave2($event,index)"
         @dragStart="onDragStart2($event, index)"
        :key="index"
        @drop="onDropTarget($event, index)"
        :get-child-payload="() => containerItem"
        :class="['source-item-container',round_arr[index]]"
        @dragover.prevent
        :data-id="index.id"
      >
        <draggable v-if="containerItem">
          <div class='dropped-item' :style="{backgroundColor:containerItem.name}" ></div>
        </draggable>
        <div v-else></div>
       </container>
   
    </div>
  </div>
     <!-- 源容器 -->
     <div v-if="!submit_status" class="source-container">
      <container
        group-name="shared"
        behaviour="move"
        v-for="(item, index) in items"
        :key="index"
        @dragEnter="onDragEnter($event,index)"
        @dragLeave="onDragLeave($event,index)"
        @drop="onDropSource($event, index)"
        @dragStart="onDragStart($event, index)"
        :get-child-payload="() => item"
        class="dropzone"
        @dragover.prevent
      >
        <draggable class="rounds" v-if="item">
          <div :style="{backgroundColor:item.name}" class="draggable-item"></div>
        </draggable>
        <div v-else></div>
      </container>
    </div>
    <div>
    </div>
    <div class="synopsis" v-if="!submit_status" >
      孟塞尔色棋是评估个人辨别色彩能力的标准检测方
案。基于孟塞尔色棋93个色相棋子的原始检测方
案，本测试为简化版孟塞尔色相d-15测试，包含15
个可移动的色棋，用递增色相的方式排列，可初步
评估个人的颜色视觉能力。本测试依赖电子设备的
颜色呈现;仅供参考，不构成医学建议。
    </div>
    <div v-else class="prompt" :style="{height:is_more?'3rem':'9rem'}" >
      人类可以看到色彩，是因为视网膜上红、蓝、绿视锥细胞
可以感知光的色彩差异，帮助人们分清颜色变化。全世界
约有2亿人有颜色辨别障碍。<br>
当某一类视锥细胞缺失或功能降低时，人的辨色能力可能
会有相应的影响。如果其中一种或多种视锥细胞功能部分
失效，便会造成色弱;如果其中功能完全失效，可能会造
成色盲。 色觉障碍的类别有多种，其中最普遍的是红绿
色弱，而黄蓝色弱则比较罕见。
<div class="prompt_more" v-if="is_more" @click="is_more=!is_more"  >
更多
</div>
    </div>
    <div class="submit_but" >
      <el-button v-if="!submit_status"  color="#FE2B54" style="width: 95%;margin: 0 auto;margin-bottom:10px;" :disabled="containers.some(item=>item===null)"  @click="handleClick">查看测试结果</el-button>
      <el-button v-if="submit_status&&!serou"  color="#FE2B54" style="width: 95%;margin: 0 auto;margin-bottom:10px;"   @click="reset">确定</el-button>
      <el-button v-if="submit_status"  color="#FFFFFF" style="width: 95%;margin: 0 auto;color: black;margin-bottom:10px; border: 0.1px solid #aaa;"   @click="reset">重新测试</el-button>
      <el-button v-if="submit_status&&serou"  color="#FE2B54" style="width: 95%;margin: 0 auto;margin-bottom:10px;"  >去设置色弱模式</el-button>
    </div>
    <!--   -->
</template>


<script setup>
import { ref, watch } from 'vue';
import { Container, Draggable } from 'vue3-smooth-dnd';
// 更多状态
const is_more=ref(true)
// 用户提交状态
const submit_status = ref(false);
// 提交结果文字提示
const result_text = ref('你拥有'+'</br>'+'优秀的辨色能力');
const items = ref([
{id:1,name: '#93709A', sourceIndex: 0 },
  {id:2,name: '#7F73B1', sourceIndex: 1 },
  {id:3,name: '#3C8691', sourceIndex: 2 },
  {id:4,name: '#588475', sourceIndex: 3 },
  {id:5,name: '#3583B4', sourceIndex: 4 },
  {id:6,name: '#9F6D6E', sourceIndex: 5 },
  {id:7,name: '#827B5E', sourceIndex: 6 },
  {id:8,name: '#9B6D87', sourceIndex: 7 },
  {id:9,name: '#3B84A7', sourceIndex: 8 },
  {id:10,name: '#A06D7C', sourceIndex: 9 },
  {id:11,name: '#3F8783', sourceIndex: 10 },
  {id:12,name: '#6C8064', sourceIndex: 11 },
  {id:13,name: '#906FA4', sourceIndex: 12},
  {id:14,name: '#39859C', sourceIndex: 13},
  {id:15,name: '#907560', sourceIndex: 14},
]);
const items2 = ref([
{id:1,name: '#93709A', sourceIndex: 0 },
  {id:2,name: '#7F73B1', sourceIndex: 1 },
  {id:3,name: '#3C8691', sourceIndex: 2 },
  {id:4,name: '#588475', sourceIndex: 3 },
  {id:5,name: '#3583B4', sourceIndex: 4 },
  {id:6,name: '#9F6D6E', sourceIndex: 5 },
  {id:7,name: '#827B5E', sourceIndex: 6 },
  {id:8,name: '#9B6D87', sourceIndex: 7 },
  {id:9,name: '#3B84A7', sourceIndex: 8 },
  {id:10,name: '#A06D7C', sourceIndex: 9 },
  {id:11,name: '#3F8783', sourceIndex: 10 },
  {id:12,name: '#6C8064', sourceIndex: 11 },
  {id:13,name: '#906FA4', sourceIndex: 12},
  {id:14,name: '#39859C', sourceIndex: 13},
  {id:15,name: '#907560', sourceIndex: 14},
]);
const result_arr=['#3781C0','#3583B4','#3B84A7','#39859C','#3C8691','#3F8783','#588475','#6C8064','#827B5E','#907560','#9F6D6E','#A06D7C','#9B6D87','#93709A','#906FA4','#7F73B1']
const round_arr=['img1','img2','img3','img4','img5','img6','img7','img8','img9','img10','img11','img12','img13','img14','img15','img16'];
const containers = ref([ {id:1,name: '#3781C0', sourceIndex: 0 }, null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,]);
let source_index='',target_index='';
const onDropSource = (dropResult, sourceIndex) => {
  console.log('onDropSource',dropResult, sourceIndex);
  // draggedItem用于区分是否是源容器相互拖拽有则是，没有则不是。
  const { removedIndex, addedIndex, payload } = dropResult;
  const draggedItem = payload;
  console.log(this);
  source_index=sourceIndex;
  console.log(target_index,73);
  console.log(draggedItem);
  if(addedIndex !== null&&!draggedItem){
    for (let index = 0; index < items2.value.length; index++) {
      if(items2.value[index].id===containers?.value[target_index]?.id){
      const targetIndex = containers.value.findIndex(
        (containerItem) => containerItem && containerItem.id === containers.value[target_index].id
      );
      if (targetIndex !== -1) {
        containers.value[targetIndex] = null;
      }
      items.value[index]=items2.value[index];
    }
      
    }
 
  }
 
};
  // 循环数组记得可以封装一下
const onDropTarget = (dropResult, targetIndex) => {
  console.log('onDropTarget',dropResult, targetIndex);
  
  const { removedIndex, addedIndex, payload } = dropResult;
  const draggedItem = payload;

  // 如果项目是从源容器拖入的
  if (removedIndex === null && addedIndex !== null && draggedItem) {
    // 如果目标容器已有项目，将其放回源容器
    if (containers.value[targetIndex]) {
      if(targetIndex>7){
       console.log(targetIndex);
          //containers.value=removeFirstNullFromIndex(containers.value,targetIndex);
          let null_value=false
          for (let i = targetIndex; i < containers.value.length; i++) {
            console.log(i);
          console.log(containers.value[i]);
            
    if (containers.value[i] === null) {
      null_value=!null_value;
      containers.value.splice(i, 1); // 从索引 i 位置删除 1 个元素
      containers.value.splice(targetIndex, 0, draggedItem);

      break; // 只删除第一个找到的 null，退出循环
    }
  }
   if(null_value){
// return
   } else{
    containers.value.splice(targetIndex+1, 0, draggedItem);
    for (let i = targetIndex; i >= 0; i--) {
      console.log(containers.value[i]);
    if (containers.value[i] === null) {
      containers.value.splice(i, 1); // 从索引 i 位置删除 1 个元素
      break; // 只删除第一个找到的 null，退出循环
    }
  }
   }     
      }else if(targetIndex<=7){
       console.log(targetIndex);
       console.log(containers.value);
        //containers.value=removeFirstNullFromIndex(containers.value,targetIndex);
        let null_value=false
        for (let i = targetIndex; i >= 0; i--) {
          console.log(i);
          console.log(containers.value[i]);
    if (containers.value[i] === null) {
      containers.value.splice(targetIndex+1, 0, draggedItem);
      console.log(i);
      null_value=!null_value;
      containers.value.splice(i, 1); // 从索引 i 位置删除 1 个元素
      break; // 只删除第一个找到的 null，退出循环
    }
  }
   if(null_value){
// return
   } else{
      containers.value.splice(targetIndex, 0, draggedItem);
      console.log(containers.value);
// return
      for (let i = targetIndex; i < containers.value.length; i++) {
      console.log(containers.value[i]);
    if (containers.value[i] === null) {
      // containers.value.splice(targetIndex, 0, draggedItem);
      containers.value.splice(i, 1); // 从索引 i 位置删除 1 个元素
      break; // 只删除第一个找到的 null，退出循环
    }
  }
   
   } 
      }
      const existingItem = containers.value[targetIndex];
      const originalSourceIndex = existingItem.sourceIndex;
      // 将已有项目放回其原始源容器
      // items.value[originalSourceIndex] = existingItem;
    }else{
  // 将新的项目放入目标容器
    containers.value[targetIndex] = draggedItem;
    }
  // 从源容器中移除项目
  const sourceIndex = draggedItem.sourceIndex;
  console.log(items.value[sourceIndex]);
    if (items.value[sourceIndex]) {
      items.value[sourceIndex] = null;
    }
  }else if(removedIndex === 0 && addedIndex === null && draggedItem===null){

    console.log('目标容器相互拖拽,移出');
    
  }else if( removedIndex=== null&&addedIndex!==null&&payload=== null){
    console.log('目标容器相互拖拽，加入');
    if(containers.value[targetIndex]){
      let obj=containers.value[target_index];
      
      // containers.value[targetIndex]=containers.value[target_index];
      containers.value.splice(target_index, 1); // 从索引 i 位置删除 1 个元素
      containers.value.splice(targetIndex, 0,obj); // 从索引 i 位置删除 1 个元素

      // containers.value[target_index]=null;
    }else if(!containers.value[targetIndex]){
      containers.value[targetIndex]=containers.value[target_index];
      containers.value[target_index]=null;
    }
    ;
    
  }
};
// 容器开始拖动
function onDragStart(event,index) {
  console.log('onDragStart',event,index);
  if(event.isSource&&event.willAcceptDrop){
    target_index=index;
  }
}
// 容器开始拖动
function onDragStart2(event,index) {
  console.log('onDragStart2',event,index);
  if(event.isSource&&event.willAcceptDrop){
    target_index=index;
  }
}
// 容器进入
function onDragEnter(event, targetIndex) {

  console.log('onDragEnter',event, targetIndex);
  
}
// 容器离开
function onDragLeave(event, targetIndex) {
  console.log('onDragLeave',event, targetIndex);
}
// 容器进入
function onDragEnter2(event, targetIndex) {

console.log('onDragEnter',event, targetIndex);

}
// 容器离开
function onDragLeave2(event, targetIndex) {
console.log('onDragLeave',event, targetIndex);
}
const serou=ref(false);
// 查看测试结果
function handleClick() {
  console.log(containers.value);
  submit_status.value=true;
  let res_arr=containers.value.map(item=>item?.name)
  console.log(res_arr);
  console.log(result_arr);
  
  if(JSON.stringify(res_arr)===JSON.stringify(result_arr)){
    result_text.value='你拥有</br>优秀的辨色能力';
  }else{
    result_text.value='辨别红色的能力可能较弱';
    serou.value=true
  }
}
// 重置事件
function reset(){
  for (let index = 0; index < containers.value.length; index++) {
    if(index==0)
    {containers.value[index]= {id:1,name: '#3781C0', sourceIndex: 0 }}else{
      containers.value[index]= null;
    }
    
  }
  console.log(containers.value);
  items.value=items2.value;
  result_text.value='';
  serou.value=false;
  submit_status.value=false;
}
// js从指定元素向后遍历
function removeFirstNullFromIndex(arr, startIndex) {
  for (let i = startIndex; i < arr.length; i++) {
    if (arr[i] === null) {
      arr.splice(i, 1); // 从索引 i 位置删除 1 个元素
      break; // 只删除第一个找到的 null，退出循环
    }
  }
  console.log(arr);
  return arr;
}

</script>


